package com.wisezone.workflow.utils;

import java.util.Iterator;
import java.util.List;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import com.wisezone.workflow.bean.WfVariable;
import com.wisezone.workflow.bean.po.NodeModule;
import com.wisezone.workflow.bean.po.ProcessModule;
import com.wisezone.workflow.bean.po.TransitionModule;
import com.wisezone.workflow.bean.po.VariableModule;

public class ProcessUtils {

    
    /**
     * xml 格式转流程模板
     * @param xmlStr
     * @return
     * @throws RuntimeException
     */
    public static ProcessModule xmlToProcess(String xmlStr) throws RuntimeException{
    	
        Document document = null;
		try {
			document = DocumentHelper.parseText(xmlStr);
		} catch (DocumentException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		} 
        Element processElement = document.getRootElement();
        ProcessModule processModule = new ProcessModule();
        NodeModule taskModule = null;
        String key = processElement.attributeValue("key");
        String processName = processElement.attributeValue("name");
        String version = processElement.attributeValue("version");
        processModule.setKey(key);
        processModule.setName(processName);
        processModule.setVersion(version);
        
        //任务节点
        List<Element> nodeList = processElement.elements();
        if(nodeList != null){
        	for(int i = 0; i < nodeList.size(); i++){
        		Element taskElement = nodeList.get(i);
        		taskModule = new NodeModule();
        		
        		//节点属性
        		taskModule.setName(taskElement.attributeValue("name"));
        		taskModule.setPosition(taskElement.attributeValue("p"));
        		taskModule.setCategory(taskElement.attributeValue("category"));
        		taskModule.setTaskCategory(taskElement.attributeValue("taskCategory"));
        		
				
				//变量列表
        		List<Element> variableList = taskElement.elements("variable");
    			for(Iterator<Element> eIt = variableList.iterator(); eIt.hasNext();){
    				Element element = eIt.next();
    				VariableModule variableModule = new VariableModule();
    				variableModule.setName(element.attributeValue("name"));
    				variableModule.setValue(element.attributeValue("value"));
    				taskModule.addVariableModule(variableModule);
    			}
        		
        		//链接节点
        		List<Element> transitionList = taskElement.elements("transition");
        		if(transitionList != null){
        			for(Iterator<Element> iter = transitionList.iterator(); iter.hasNext();){
        				Element tranElement = iter.next();
        				TransitionModule transitionModule = new TransitionModule();
        				transitionModule.setName(tranElement.attributeValue("name"));
        				transitionModule.setFrom(taskModule.getName());
        				transitionModule.setTo(tranElement.attributeValue("to"));
        				transitionModule.setPosition(tranElement.attributeValue("p"));
        				transitionModule.setCondition(tranElement.elementText("condition"));
        				taskModule.addTransitionModule(transitionModule);
        			}
        		}
        		processModule.addNodeModule(taskModule);
        	}
        }
		
        return processModule;
    }
    
	/**
	 * json 格式转 流程模板对象
	 * @param jsonStr
	 * @return
	 * @throws RuntimeException
	 */
	public static ProcessModule jsonToProcess(String jsonStr) throws RuntimeException {
		
		ProcessModule processModule = null;
		if(StringUtils.isEmpty(jsonStr)){
			throw new IllegalArgumentException("参数 jsonStr 字符不能为空");
		}
		JSONObject jsObject = null;
		try {
			jsObject = new JSONObject(jsonStr);
		} catch (JSONException e) {
			throw new IllegalArgumentException("参数 jsonStr 格式不合法");
		} 
		
			JSONObject templateForm = jsObject.getJSONObject("form");
			if(templateForm == null){
				throw new RuntimeException("流程模板不能为空");
			}
			String key = getStringFromJson(templateForm, "key"); 
			String name = getStringFromJson(templateForm, "name"); 
			String version = getStringFromJson(templateForm, "version"); 
			String description = getStringFromJson(templateForm, "description"); 
			
			processModule = new ProcessModule();
			processModule.setKey(key);
			processModule.setName(name);
			processModule.setVersion(version);
			processModule.setDescription(description);
			
			//***************模板变量处理开始***************//
			JSONObject variableMap = templateForm.getJSONObject("variableMap");
			if(variableMap != null){
				
				JSONArray variableArray = variableMap.getJSONArray("dataList");
				if(variableArray != null && variableArray.length() > 0){
					
					for(int j = 0; j < variableArray.length(); j++){
						
						JSONObject variableObj = variableArray.getJSONObject(j);
						if(variableObj == null){
							continue;
						}
						String id = getStringFromJson(variableObj, "key");
						JSONObject valueObj = variableObj.getJSONObject("value");
						if(valueObj == null){
							continue;
						}
						String variableName = getStringFromJson(valueObj, "name");
						String variableValue = getStringFromJson(valueObj, "value");
						VariableModule variableModule = new VariableModule();
						variableModule.setId(id);
						variableModule.setName(variableName);
						variableModule.setValue(variableValue);
						processModule.addVariableModule(variableModule);
					}
				}
				//***************模板变量处理结束***************//
			}
			
			JSONArray nodeArray = jsObject.getJSONArray("nodeArray");
			if(nodeArray == null || nodeArray.length() == 0){
				throw new RuntimeException("节点数目不能为空");
			}
			
			
			for(int i = 0; i < nodeArray.length(); i++){
				
				JSONObject nodeObj = nodeArray.getJSONObject(i);
				if(nodeObj == null){
					continue;
				}
				if(!nodeObj.has("form")){
					continue;
				}
				JSONObject nodeForm = nodeObj.getJSONObject("form");
				String nodeId = getStringFromJson(nodeForm, "id");
				String nodeName = getStringFromJson(nodeForm, "name");
				String category = getStringFromJson(nodeForm, "category");
				String taskCategory = getStringFromJson(nodeForm, "taskCategory");
				
				if(!nodeObj.has("cssStyle")){
					continue;
				}
				JSONObject nodeCssStyle = nodeObj.getJSONObject("cssStyle");
				String posLeft = getStringFromJson(nodeCssStyle, "posLeft");
				String posTop = getStringFromJson(nodeCssStyle, "posTop");
				String posWidth = getStringFromJson(nodeCssStyle, "posWidth");
				String posHeight = getStringFromJson(nodeCssStyle, "posHeight");
				
				NodeModule nodeModule = new NodeModule();
				nodeModule.setId(nodeId);
				nodeModule.setName(nodeName);
				nodeModule.setCategory(category);
				nodeModule.setTaskCategory(taskCategory);
				
				String position = posWidth+","+posHeight+":"+posLeft+","+posTop;
				nodeModule.setPosition(position);  //宽,高：left,top
				
				processModule.addNodeModule(nodeModule);
				
				//***************节点变量处理开始***************//
				variableMap = nodeForm.getJSONObject("variableMap");
				JSONArray variableArray = variableMap.getJSONArray("dataList");
				if(variableArray != null && variableArray.length() > 0){
					
					for(int j = 0; j < variableArray.length(); j++){
						
						JSONObject variableObj = variableArray.getJSONObject(j);
						if(variableObj == null){
							continue;
						}
						String id = getStringFromJson(variableObj, "key");
						JSONObject valueObj = variableObj.getJSONObject("value");
						if(valueObj == null){
							continue;
						}
						String variableName = getStringFromJson(valueObj, "name");
						String variableValue = getStringFromJson(valueObj, "value");
						VariableModule variableModule = new VariableModule();
						variableModule.setId(id);
						variableModule.setName(variableName);
						variableModule.setValue(variableValue);
						nodeModule.addVariableModule(variableModule);
					}
				}
				//***************节点变量处理结束***************//
				
				
				//***************链接处理开始***************//
				if(!nodeObj.has("linkArray")){
					continue;
				}
				JSONArray linkArray = nodeObj.getJSONArray("linkArray");
				if(linkArray != null && linkArray.length() > 0){
					for(int j = 0; j < linkArray.length(); j++){
						JSONObject linkObj = linkArray.getJSONObject(j);
						if(linkObj == null){
							continue;
						}
						
						if(!linkObj.has("form")){
							continue;
						}
						JSONObject linkForm = linkObj.getJSONObject("form");
						String linkName = getStringFromJson(linkForm, "name");
						String linkCondition = getStringFromJson(linkForm, "condition");
						String inputNodeId = getStringFromJson(linkForm, "inputNodeId");
						String outputNodeId = getStringFromJson(linkForm, "outputNodeId");
						String inputNodeName = getStringFromJson(linkForm, "inputNodeName");
						String outputNodeName = getStringFromJson(linkForm, "outputNodeName");
						
						if(!linkObj.has("cssStyle")){
							continue;
						}
						JSONObject linkCssStyle = linkObj.getJSONObject("cssStyle");
						String fromX = getStringFromJson(linkCssStyle,"fromX");
						String fromY = getStringFromJson(linkCssStyle,"fromY");
						String toX = getStringFromJson(linkCssStyle,"toX");
						String toY = getStringFromJson(linkCssStyle,"toY");
						
						TransitionModule transitionModule = new TransitionModule();
						transitionModule.setName(linkName);
						transitionModule.setCondition(linkCondition);
						transitionModule.setFromId(inputNodeId);
						transitionModule.setToId(outputNodeId);
						transitionModule.setFrom(inputNodeName);
						transitionModule.setTo(outputNodeName);
						
						position = fromX+","+fromY+":"+toX+","+toY;
						transitionModule.setPosition(position);
						nodeModule.addTransitionModule(transitionModule);
						//***************链接处理结束***************//
					}
				}
			}
			
		return processModule;
	}
	
	/**
	 * 获得String 值从json 数据中
	 * @param jsonObj
	 * @param key
	 * @return
	 */
	private static String getStringFromJson(JSONObject jsonObj,String key){
		
		if(jsonObj.has(key)){
			try {
				return jsonObj.getString(key);
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}
	
	/**
	 * 获得Integer 值从json 数据中
	 * @param jsonObj
	 * @param key
	 * @return
	 */
	private static Integer getIntegerFromJson(JSONObject jsonObj,String key){
		
		if(jsonObj.has(key)){
			try {
				return jsonObj.getInt(key);
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}
    
	/**
	 * 流程模板转xml
	 * @param processModule
	 * @return
	 * @throws RuntimeException
	 */
    public static String processToXml(ProcessModule processModule) throws RuntimeException{
		
		if(processModule == null){
			throw new IllegalArgumentException("参数 processModule 不能为空");
		}
		StringBuffer sb = new StringBuffer();
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
		sb.append("<process key=\""+processModule.getKey()+"\" name=\""+processModule.getName()+"\" version=\""+processModule.getVersion()+"\">\n");
		sb.append("  <description>"+processModule.getDescription()+"</description>\n");
		
		//模板变量
		List<VariableModule> variableList = processModule.getVariableModules();
		if(variableList != null && variableList.size() > 0){
			for(VariableModule variableModule : variableList){
				if(variableModule == null){
					continue;
				}
				String variableName = variableModule.getName();
				String variableValue = variableModule.getValue();
				sb.append("  <variable name=\""+variableName+"\" value=\""+variableValue+"\" />\n");
			}
		}
		
		//节点处理
		List<NodeModule> nodeList = processModule.getNodeModules();
		if(nodeList == null || nodeList.size() == 0){
			throw new IllegalArgumentException("参数 processModule nodeList 不能为空");
		}
		for(NodeModule nodeModule : nodeList){
			if(nodeModule == null){
				continue;
			}
			String category = nodeModule.getCategory();
			String position = nodeModule.getPosition();
			String name = nodeModule.getName();
			String taskCategory = nodeModule.getTaskCategory();
			sb.append("  <node category=\""+category+"\" p=\""+position+"\" name=\""+name+"\" ");
			if(StringUtils.isNotEmpty(taskCategory)){
				sb.append("taskCategory=\""+taskCategory+"\" ");
			}
			sb.append(">\n");
			
			//处理节点变量
			variableList = nodeModule.getVariableModules();
			if(variableList != null && variableList.size() > 0){
				for(VariableModule variableModule : variableList){
					if(variableModule == null){
						continue;
					}
					String variableName = variableModule.getName();
					String variableValue = variableModule.getValue();
					sb.append("\t<variable name=\""+variableName+"\" value=\""+variableValue+"\" />\n");
				}
			}
			
			//处理链接
			List<TransitionModule> tranList = nodeModule.getTransitionModules();
			if(tranList != null && tranList.size() > 0){
				for(TransitionModule tranModule : tranList){
					if(tranModule == null){
						continue;
					}
					String fromName = tranModule.getName();
					String toName = tranModule.getTo();
					String condition = tranModule.getCondition();
					String tranPosition = tranModule.getPosition();
					sb.append("\t<transition p=\""+tranPosition+"\" name=\""+fromName+"\" to=\""+toName+"\">\n");
					if(StringUtils.isNotEmpty(condition)){
						sb.append("\t\t<condition><![CDATA[ "+condition+" ]]></condition>\n");
					}
					sb.append("\t</transition>\n");
				}
			}
			sb.append(" </node>\n");
		}
		sb.append("</process>");  
		
		return sb.toString();
		
	}
    
    /**
     * 设置json 数据
     * @param jsonVarMapArray
     * @param variable
     * @throws RuntimeException
     */
    public static void setVarJson(JSONArray jsonVarMapArray,WfVariable variable,String act) throws RuntimeException{
		
    	if(jsonVarMapArray == null){
			throw new IllegalArgumentException("jsonVarMapArray 不能为空");
		}
    	if(variable == null){
    		throw new IllegalArgumentException("variable 不能为空");
    	}
		for(int i = 0; i < jsonVarMapArray.length(); i++){
			JSONObject jsonVarObj = jsonVarMapArray.getJSONObject(i);
		    if(jsonVarObj == null){
		    	continue;
		    }
		    if(!jsonVarObj.has("value")){
		    	continue;
		    }
		    JSONObject jsonValObj = jsonVarObj.getJSONObject("value");
		    if(jsonValObj == null){
		    	continue;
		    }
            String name = jsonValObj.getString("name");
            if(variable.getName().equals(name)){
            	if(act.equals("saveOrUpdate")){
            		jsonValObj.set("value", variable.getValue());
            	}else{
            		jsonVarMapArray.put(i, "");
            		
            	}
            }
            
		}
    }
    
	
}
